package com.example.service;

import org.glassfish.jersey.client.rx.RxClient;
import org.glassfish.jersey.client.rx.RxWebTarget;
import org.glassfish.jersey.client.rx.rxjava.RxObservableInvoker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import rx.Observable;

import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.Response;
import java.util.Map;
import java.util.Optional;

@Component
public class HttpClient {
    @Autowired
    private RxClient<RxObservableInvoker> rxClient;

    public Observable<Map<String,Object>> getUser(){

            String uri="http://localhost:8881/threadtest";

        RxWebTarget<RxObservableInvoker> webTarget=rxClient.target(uri);
        MultivaluedHashMap<String,Object> headers=new MultivaluedHashMap<>();
        headers.add("Content-type","application/json");
        System.out.println("HttpClient getUser() "+ Thread.currentThread().getName());
        return webTarget.request(MediaType.APPLICATION_JSON_TYPE).rx().get().single().map(this::parse);



    }

    private Map<String,Object> parse(Response response){

        System.out.println(response.getStatus());

        GenericType<Map<String,Object>> AS_MAP= new GenericType<Map<String,Object>>(){};
        Optional<Map<String,Object>> json=Optional.ofNullable(response.readEntity(AS_MAP));
        json.get().put("downstream-resp-status",response.getStatus());
        return json.orElseThrow(()->new IllegalStateException("received invalid HTTP ENTITY"));

    }

    public Observable<Map<String,Object>> getUser01(){

        String uri="http://localhost:8880/threadtest";

        RxWebTarget<RxObservableInvoker> webTarget=rxClient.target(uri);
        MultivaluedHashMap<String,Object> headers=new MultivaluedHashMap<>();
        headers.add("Content-type","application/json");
        System.out.println("HttpClient getUser01() "+ Thread.currentThread().getName());
        return webTarget.request(MediaType.APPLICATION_JSON_TYPE).rx().get().single().map(this::parse);

    }


    @Async("AsyncTestExecuter")
    public String asyncTest(){
        System.out.println("HttpClient async test thread: "+ Thread.currentThread().getName());
        return "HttpClient async test";

    }
}
